﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using YArchitech.Controls;
using YArchitech.HVAC;
using YArchitech.LIB;
using YArchitech.Revit;
using YArchitech.Revit.RevitExtension;

namespace YArchitech.Plumbing
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class ThwartwiseCreate : IExternalCommand
	{
		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		public XYZ getxyz(Pipe pipe)
		{
			Line curve = (pipe.Location as LocationCurve).Curve as Line;
			return (curve.GetEndPoint(0) + curve.GetEndPoint(1)) / 2.0;
		}

		public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			Transaction transaction = null;
			UIApplication application = commandData.Application;
			Autodesk.Revit.ApplicationServices.Application application2 = application.Application;
			Document document = application.ActiveUIDocument.Document;
			UIDocument activeUIDocument = commandData.Application.ActiveUIDocument;
			List<string> levelUp = new List<string>();
			levelUp = YJKElementFilter.GetElementNameByClass(typeof(Level), document);
			double offset = 0.0;
			HYPipeConnect myPipeConnect = new HYPipeConnect();
			List<ViewType> list = YJKRevitTools.ListViewNeed(1);
            list.Add((ViewType)3);
			if (!YJKRevitTools.ViewCheck(activeUIDocument, list))
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			if (ThwartwiseCreate.hWndRevit == null)
			{
				ThwartwiseCreate.hWndRevit = new YJKWindowHandle(Process.GetCurrentProcess().MainWindowHandle);
			}
			FormCreateThwartwisePipe formCreateThwartwisePipe = new FormCreateThwartwisePipe(document, levelUp);
			if ((int)document.ActiveView.ViewType == 3)
			{
				formCreateThwartwisePipe.textBoxLevel.Enabled = false;
				formCreateThwartwisePipe.hyTextBox1.Enabled = false;
				formCreateThwartwisePipe.textBoxOffset.Enabled = false;
			}
			formCreateThwartwisePipe.Show(ThwartwiseCreate.hWndRevit);
			int wMsg = 7;
			ThwartwiseCreate.SendMessage(ThwartwiseCreate.hWndRevit.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
			Result result;
			for (;;)
			{
				try
				{
					Plane plane = null;
					if ((int)document.ActiveView.ViewType == 3)
					{
						plane = this.CreateWorkPlane(document);
					}
					HYSystemType.IsOpenTran = false;
					XYZ xyz = activeUIDocument.Selection.PickPoint("请选择绘制横管所基于线的起点（坡度将以该点为起点）...");
					XYZ xyz2 = null;
					if (xyz != null)
					{
						HYSystemType.IsOpenTran = true;
						Pipe pipe = null;
						Pipe pipe2 = null;
						for (;;)
						{
							transaction = new Transaction(document, "绘制横管");
							transaction.Start();
							try
							{
								if ((int)document.ActiveView.ViewType != 3)
								{
									offset = double.Parse(formCreateThwartwisePipe.textBoxOffset.Text);
								}
								if (formCreateThwartwisePipe.Visible)
								{
									using (PipeCreateJigPolarAxis pipeCreateJigPolarAxis = new PipeCreateJigPolarAxis(activeUIDocument, offset, formCreateThwartwisePipe))
									{
										pipeCreateJigPolarAxis.StartPoint = xyz;
										pipeCreateJigPolarAxis.DrawSize = true;
                                        System.Windows.Forms.Application.DoEvents();
										pipeCreateJigPolarAxis.SetPromptState("", false, true);
										xyz2 = pipeCreateJigPolarAxis.PickEndPoint(xyz, "请选择绘制横管所基于线的终点...");
										pipeCreateJigPolarAxis.Dispose();
									}
									if (xyz2 == null)
									{
										break;
									}
									if (xyz2.IsAlmostEqualTo(xyz))
									{
										MessageBox.Show("选择的两点过于接近，无法创建！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
										break;
									}
									if (formCreateThwartwisePipe.systemType.currentSystemTypeInfo == null || formCreateThwartwisePipe.systemType.currentSystemTypeInfo.SysType == null || formCreateThwartwisePipe.systemType.currentSystemTypeInfo.PipeType == null)
									{
										YJKMessageBox.Show("需要选择系统类型");
										break;
									}
									if ((int)document.ActiveView.ViewType == 3)
									{
										PipeType pipeType = formCreateThwartwisePipe.Get_PipeType(document, formCreateThwartwisePipe.systemType.currentSystemTypeInfo.PipeType);
										PipingSystemType pipingSystemType = formCreateThwartwisePipe.Get_PipingSystemType(document, formCreateThwartwisePipe.systemType.currentSystemTypeInfo.SysType);
										string text = formCreateThwartwisePipe.comboBoxPipeDiameter.Text;
										List<Pipe> elevationIntersectPipes = this.GetElevationIntersectPipes(xyz, plane.Normal, document);
										if (elevationIntersectPipes.Count<Pipe>() > 0)
										{
											Pipe connPipe = this.GetConnPipe(elevationIntersectPipes, xyz);
											XYZ project = new YJKPiping<Pipe>(connPipe).GetProject(xyz);
											XYZ xyz3 = project.Subtract(xyz);
											XYZ xyz4 = xyz2.Add(xyz3);
											if (YJKRevitTools.getNewXYZDeriction(project, xyz4) != null)
											{
												pipe2 = document.CreatHYPipe(pipingSystemType, pipeType, formCreateThwartwisePipe.Get_Level(document), project, xyz4, double.Parse(text));
											}
											List<Pipe> list2 = new List<Pipe>();
											pipe = pipe2;
											list2.Add(connPipe);
											list2.Add(pipe);
											SubTransaction subTransaction = new SubTransaction(document);
											subTransaction.Start();
											try
											{
												this.ConnectPipes(list2, ref pipe, myPipeConnect);
												subTransaction.Commit();
												goto IL_3A2;
											}
											catch (Exception)
											{
												subTransaction.RollBack();
												goto IL_3A2;
											}
										}
										if (YJKRevitTools.getNewXYZDeriction(xyz, xyz2) != null)
										{
											pipe2 = document.CreatHYPipe(pipingSystemType, pipeType, formCreateThwartwisePipe.Get_Level(document), xyz, xyz2, double.Parse(text));
										}
										pipe = pipe2;
										IL_3A2:
										XYZ point = xyz;
										xyz = xyz2;
										xyz2 = null;
										List<Element> elementByCollision = this.GetElementByCollision(pipe, BuiltInCategory.OST_PipeCurves, document);
										this.CrossElevationConnPipes(elementByCollision, pipe, point, plane.Normal, myPipeConnect);
									}
									else
									{
										double num = double.Parse(formCreateThwartwisePipe.textBoxLevel.Text) * 1000.0 + formCreateThwartwisePipe.Get_Level(document).ProjectElevation * 304.8;
										offset = double.Parse(formCreateThwartwisePipe.textBoxOffset.Text);
										PipeType pipeType = formCreateThwartwisePipe.Get_PipeType(document, formCreateThwartwisePipe.systemType.currentSystemTypeInfo.PipeType);
										PipingSystemType pipingSystemType = formCreateThwartwisePipe.Get_PipingSystemType(document, formCreateThwartwisePipe.systemType.currentSystemTypeInfo.SysType);
										string text = formCreateThwartwisePipe.comboBoxPipeDiameter.Text;
										double slope;
										if (formCreateThwartwisePipe.hyTextBox1.Visible)
										{
											slope = double.Parse(formCreateThwartwisePipe.hyTextBox1.Text);
										}
										else
										{
											slope = 0.0;
										}
										XYZ newXYZDeriction = YJKRevitTools.getNewXYZDeriction(xyz, xyz2);
										HYCreatePipeHelper hycreatePipeHelper = new HYCreatePipeHelper();
										if (newXYZDeriction != null)
										{
											if (pipe != null && pipe.IsValidObject)
											{
												double createPipeLevel = this.GetCreatePipeLevel(document, ref pipe, xyz, xyz2, num, slope, offset, newXYZDeriction, hycreatePipeHelper);
												pipe2 = hycreatePipeHelper.DrawThwartwisePipe(document, offset, createPipeLevel, xyz, xyz2, pipeType, double.Parse(text), pipingSystemType, slope, newXYZDeriction);
											}
											else
											{
												pipe2 = hycreatePipeHelper.DrawThwartwisePipe(document, offset, num, xyz, xyz2, pipeType, double.Parse(text), pipingSystemType, slope, newXYZDeriction);
											}
										}
										Line curve = (pipe2.Location as LocationCurve).Curve as Line;
										formCreateThwartwisePipe.textBoxLevel.Text = Math.Round((curve.GetEndPoint(1).Z - formCreateThwartwisePipe.Get_Level(document).ProjectElevation) * 0.3048, 3).ToString();
										Line pipeline = YJKLineEx.YJKGetBound(xyz, xyz2);
										XYZ newParallelPipeXYZ = hycreatePipeHelper.getNewParallelPipeXYZ(xyz, pipeline, offset, newXYZDeriction);
										XYZ start = xyz;
										xyz = xyz2;
										xyz2 = null;
										if (pipe != null && pipe.IsValidObject && pipe2 != null)
										{
											Curve curve2 = (pipe.Location as LocationCurve).Curve;
											Curve curve3 = (pipe2.Location as LocationCurve).Curve;
											YJKLine hyline = new YJKLine(curve2.GetEndPoint(0), curve2.GetEndPoint(1));
											YJKLine hyline2 = new YJKLine(curve3.GetEndPoint(0), curve3.GetEndPoint(1));
											if (!hyline.IsLineOnLine(hyline2.Line) && !hyline.IsXYParallel(hyline2.Line))
											{
												List<Pipe> list3 = this.ExtendPipe(new List<Pipe>
												{
													pipe,
													pipe2
												}, start);
												if (list3 != null)
												{
													XYZ xyz5 = hyline.IntersectionPoint(hyline2.Line);
													int num2 = 1;
													int num3 = 1;
													if (xyz5 != null)
													{
														num2 = (hyline.EndPoint.IsAlmostEqualTo(xyz5, 0.001) ? 1 : -1);
														num3 = (hyline2.StartPoint.IsAlmostEqualTo(xyz5, 0.001) ? 1 : -1);
													}
													XYZ xyz6 = (hyline.EndPoint - hyline.StartPoint).Normalize() * (double)num2;
													XYZ xyz7 = (hyline2.EndPoint - hyline2.StartPoint).Normalize() * (double)num3;
													YJKPipeConnectorHelper hypipeConnectorHelper = new YJKPipeConnectorHelper();
													if ((Math.Abs(xyz6.X) < 1E-06 && Math.Abs(xyz7.Y) < 1E-06) || (Math.Abs(xyz6.Y) < 1E-06 && Math.Abs(xyz7.X) < 1E-06))
													{
														if (!this.NewElbowFitting(list3, true))
														{
															MessageBox.Show("没有可以使用的族配置，请检查Revit的族配置", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
															transaction.RollBack();
															break;
														}
													}
													else if (xyz6.AngleTo(xyz7) * 180.0 / Math.PI <= 90.0)
													{
														if (!this.NewElbowFitting(list3, true))
														{
															MessageBox.Show("没有可以使用的族配置，请检查Revit的族配置", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
															transaction.RollBack();
															break;
														}
													}
													else
													{
														hypipeConnectorHelper.connect45Elbow(pipe, this.getxyz(pipe), pipe2, this.getxyz(pipe2), document);
													}
												}
											}
										}
										pipe = pipe2;
										List<Pipe> pickPipe = this.GetPickPipe(newParallelPipeXYZ, 0.032808398950131233, document);
										SubTransaction subTransaction2 = new SubTransaction(document);
										subTransaction2.Start();
										try
										{
											this.ConnectPipes(pickPipe, ref pipe, myPipeConnect, newParallelPipeXYZ);
											new YJKRotateFamilyInstance().MovePiping(pipe);
											subTransaction2.Commit();
										}
										catch (Exception)
										{
											subTransaction2.RollBack();
										}
										List<Element> elementByCollision2 = this.GetElementByCollision(pipe, BuiltInCategory.OST_PipeCurves, document);
										this.CrossConnPipes(elementByCollision2, ref pipe, newParallelPipeXYZ, myPipeConnect);
									}
								}
							}
							catch (Autodesk.Revit.Exceptions.OperationCanceledException)
							{
								pipe = null;
								transaction.RollBack();
								break;
							}
							document.Regenerate();
							transaction.Commit();
						}
						continue;
					}
					formCreateThwartwisePipe.Close();
					result = Autodesk.Revit.UI.Result.Succeeded;
				}
				catch (Autodesk.Revit.Exceptions.OperationCanceledException)
				{
					formCreateThwartwisePipe.Close();
					result = Autodesk.Revit.UI.Result.Succeeded;
				}
				catch (Exception ex)
				{
					if (ex.Message.Contains("Fitting cannot be created between the input connectors because the angle between them is too small or too large."))
					{
						MessageBox.Show("您绘制管道与上一次绘制管道夹角过大或过小！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					}
					else if (ex.Message.Contains("failed to insert elbow."))
					{
						MessageBox.Show("没有可以使用的族配置，请检查Revit的族配置", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					}
					else
					{
						MessageBox.Show(ex.Message, "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					}
					this.EndTransation(transaction, false);
					formCreateThwartwisePipe.Close();
					result = Autodesk.Revit.UI.Result.Succeeded;
				}
				finally
				{
					this.EndTransation(transaction, true);
				}
				break;
			}
			return result;
		}

		public void EndTransation(Transaction tran, bool beSure)
		{
			if (tran != null)
			{
				TransactionStatus status = tran.GetStatus();
				if ((int)status == 1)
				{
					if (beSure)
					{
						tran.Commit();
						return;
					}
					tran.RollBack();
					return;
				}
				else if ((int)status == 5)
				{
					tran.RollBack();
				}
			}
		}

		public double GetCreatePipeLevel(Autodesk.Revit.DB.Document doc, ref Pipe pipe, XYZ start, XYZ end, double level, double slope, double offset, XYZ xyzPoint, HYCreatePipeHelper help)
		{
			Line line = (pipe.Location as LocationCurve).Curve as Line;
			XYZ xyz = new XYZ(line.GetEndPoint(0).X, line.GetEndPoint(0).Y, 0.0);
			XYZ xyz2 = new XYZ(line.GetEndPoint(1).X, line.GetEndPoint(1).Y, 0.0);
			YJKLine hyline = new YJKLine(xyz, xyz2);
			if (xyz.DistanceTo(start) < xyz2.DistanceTo(start))
			{
				XYZ xyz3 = xyz;
				xyz = xyz2;
				xyz2 = xyz3;
			}
			Line pipeline = YJKLineEx.YJKGetBound(start, end);
			XYZ oldXYZ = new XYZ(start.X, start.Y, 0.0);
			XYZ oldXYZ2 = new XYZ(end.X, end.Y, 0.0);
			XYZ newParallelPipeXYZ = help.getNewParallelPipeXYZ(oldXYZ, pipeline, offset, xyzPoint);
			XYZ newParallelPipeXYZ2 = help.getNewParallelPipeXYZ(oldXYZ2, pipeline, offset, xyzPoint);
			YJKLine hyline2 = new YJKLine(newParallelPipeXYZ, newParallelPipeXYZ2);
			XYZ xyz4 = hyline.IntersectionPoint(hyline2.Line, true);
			if (xyz4 == null)
			{
				return level;
			}
			int num = (Math.Abs(xyz.DistanceTo(xyz4) - (xyz.DistanceTo(xyz2) + xyz2.DistanceTo(xyz4))) < 0.001) ? 1 : -1;
			int num2 = (Math.Abs(xyz4.DistanceTo(newParallelPipeXYZ2) - (xyz4.DistanceTo(newParallelPipeXYZ) + newParallelPipeXYZ.DistanceTo(newParallelPipeXYZ2))) < 0.001) ? 1 : -1;
			return level + slope * xyz2.DistanceTo(xyz4) * 304.8 / 100.0 * (double)num + slope * xyz4.DistanceTo(newParallelPipeXYZ) * 304.8 / 100.0 * (double)num2;
		}

		public Plane CreateWorkPlane(Autodesk.Revit.DB.Document doc)
		{
			Transaction transaction = new Transaction(doc, "创建工作平面");
			transaction.Start();
			Plane plane = null;
			if (doc.ActiveView.SketchPlane == null)
			{
				string b = RevitVersionFuncs.GetViewName(doc.ActiveView).Split(new char[]
				{
					':'
				}).Last<string>();
				FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
				filteredElementCollector.OfCategory(BuiltInCategory.OST_Viewers);
				foreach (Element elem in filteredElementCollector)
				{
					ElementId elementId = elem.GetParameter("无").AsElementId();
					Element element = doc.GetElement(elementId);
					if (element.Name == b)
					{
						plane = (element as SketchPlane).GetPlane();
						break;
					}
				}
				doc.ActiveView.SketchPlane = doc.CreatYJKSketchPlane(plane);
				doc.Regenerate();
			}
			else
			{
				plane = doc.ActiveView.SketchPlane.GetPlane();
			}
			transaction.Commit();
			return plane;
		}

		public List<Element> GetElementByCollision(Element tagElement, BuiltInCategory needElement, Autodesk.Revit.DB.Document doc)
		{
			List<Element> list = new List<Element>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			ElementIntersectsElementFilter elementIntersectsElementFilter = new ElementIntersectsElementFilter(tagElement);
			filteredElementCollector.WherePasses(elementIntersectsElementFilter);
			foreach (Element element in filteredElementCollector)
			{
                if (element.Category.Id.IntegerValue == (int)needElement)
				{
					list.Add(element);
				}
			}
			return list;
		}

		public List<Pipe> GetPickPipe(XYZ point, double size, Autodesk.Revit.DB.Document doc)
		{
			XYZ point2 = new XYZ(point.X + size, point.Y + size, point.Z);
			XYZ point3 = new XYZ(point.X - size, point.Y - size, point.Z);
			List<Pipe> list = new List<Pipe>();
			BoundingBoxIntersectsFilter boundingBoxIntersectsFilter = new BoundingBoxIntersectsFilter(RevitAPIUIOperate.CreatOutLine(RevitAPIUIOperate.GetViewRange2(doc.ActiveView, false), point2, point3));
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			filteredElementCollector.OfClass(typeof(Pipe)).OfCategory(BuiltInCategory.OST_PipeCurves).WherePasses(boundingBoxIntersectsFilter);
			XYZ end = new XYZ(point.X, point.Y, point.Z + 10.0);
			YJKLine hyline = new YJKLine(point, end);
			foreach (Element element in filteredElementCollector)
			{
				Pipe pipe = (Pipe)element;
				YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(pipe);
				YJKLine hyline2 = new YJKLine(hypiping.StartConnector.Origin, hypiping.EndConnector.Origin);
				if (this.GetDPLineDistance2(hyline2.Line, hyline) != -1.0 && this.GetDPLineDistance2(hyline2.Line, hyline) <= pipe.GetParameter("外径").AsDouble() / 2.0)
				{
					list.Add(pipe);
				}
			}
			return list;
		}

		public List<Pipe> GetElevationIntersectPipes(XYZ point, XYZ normal, Autodesk.Revit.DB.Document doc)
		{
			List<Pipe> list = new List<Pipe>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			filteredElementCollector.OfClass(typeof(Pipe)).OfCategory(BuiltInCategory.OST_PipeCurves);
			XYZ end = point.Add(normal);
			YJKLine hyline = new YJKLine(point, end);
			foreach (Element element in filteredElementCollector)
			{
				Pipe pipe = (Pipe)element;
				YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(pipe);
				YJKLine hyline2 = new YJKLine(hypiping.StartConnector.Origin, hypiping.EndConnector.Origin);
				if (this.GetDPLineDistance2(hyline2.Line, hyline) != -1.0 && this.GetDPLineDistance2(hyline2.Line, hyline) <= pipe.GetParameter("外径").AsDouble() / 2.0)
				{
					list.Add(pipe);
				}
			}
			return list;
		}

		public Pipe GetConnPipe(List<Pipe> pipes, XYZ point)
		{
			SortedDictionary<double, Element> sortedDictionary = new SortedDictionary<double, Element>();
			foreach (Element element in pipes)
			{
				Line line = (element.Location as LocationCurve).Curve as Line;
				double distance = new YJKLine(line.GetEndPoint(0), line.GetEndPoint(1)).GetDistance(point);
				sortedDictionary.Add(distance, element);
			}
			return sortedDictionary.First<KeyValuePair<double, Element>>().Value as Pipe;
		}

		public double GetDPLineDistance2(Line otherLine, YJKLine hyline1)
		{
			double num = -1.0;
			if (!hyline1.IsParallel(otherLine))
			{
				XYZ hyendPoint = otherLine.GetEndPoint(0);
				XYZ hyendPoint2 = otherLine.GetEndPoint(1);
				XYZ xyz = YJKRevitTools.GetDLineP(hyline1.StartPoint, hyline1.EndPoint, hyendPoint, hyendPoint2);
				if (!new YJKLine(hyendPoint, hyendPoint2).IsPointOnLine(xyz))
				{
					xyz = ((xyz.DistanceTo(hyendPoint) < xyz.DistanceTo(hyendPoint2)) ? hyendPoint : hyendPoint2);
				}
				XYZ dlineP = YJKRevitTools.GetDLineP(hyendPoint, hyendPoint2, hyline1.StartPoint, hyline1.EndPoint);
				num = xyz.DistanceTo(dlineP);
				num = Math.Round(num, 3, MidpointRounding.AwayFromZero);
			}
			return num;
		}

		public void ConnectPipes(List<Pipe> pipes, ref Pipe pipe, HYPipeConnect myPipeConnect)
		{
			switch (new YJKPiping<Pipe>(pipes[0]).CheckPipingsPosition(pipes[1]))
			{
			case 10:
				this.SameLineConnPipes(pipes, myPipeConnect);
				break;
			case 12:
				this.SamePlaneElbowConnPipes(pipes);
				break;
			case 13:
				this.SamePlaneTeeConnPipes(pipes, myPipeConnect);
				break;
			}
			if (pipe != null && !pipe.IsValidObject)
			{
				pipe = pipes[0];
			}
		}

		public bool ConnectPipes(List<Pipe> GlobalPipe, ref Pipe pipe, HYPipeConnect myPipeConnect, XYZ point)
		{
			if (GlobalPipe.Count<Pipe>() != 2)
			{
				return false;
			}
			bool result = true;
			IList<Pipe> list = new List<Pipe>();
			Pipe pipe2 = (GlobalPipe[0].Id == pipe.Id) ? GlobalPipe[1] : GlobalPipe[0];
			if (!new RefrigerantPipeCreate().FilterPipeType(pipe2, pipe))
			{
				return false;
			}
			list.Add(pipe2);
			list.Add(pipe);
			new YJKPiping<Pipe>(pipe2);
			int num = this.CheckPipePosition(pipe2, pipe);
			switch (num)
			{
			case 10:
				this.SameLineConnPipes(list, myPipeConnect);
				break;
			case 11:
				break;
			case 12:
				this.SamePlaneElbowConnPipes(list);
				break;
			case 13:
				this.SamePlaneTeeConnPipes(list, myPipeConnect);
				break;
			default:
				if (num != 22)
				{
					if (num == 23)
					{
						this.AntaraficialTeeConnPipes(list, myPipeConnect, point);
					}
				}
				else
				{
					this.AntarafacialElbowConnPipes(list, myPipeConnect, point);
				}
				break;
			}
			if (pipe != null && !pipe.IsValidObject)
			{
				pipe = pipe2;
			}
			return result;
		}

		public int CheckPipePosition(Pipe pipe1, Pipe pipe2)
		{
			int result = 0;
			double diameter = pipe1.Diameter;
			YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(pipe1);
			YJKPiping<Pipe> hypiping2 = new YJKPiping<Pipe>(pipe2);
			Curve curve = (pipe1.Location as LocationCurve).Curve;
			Line otherLine = (pipe2.Location as LocationCurve).Curve as Line;
			YJKLine hyline = new YJKLine(hypiping.StartConnector.Origin, hypiping.EndConnector.Origin);
			YJKLine hyline2 = new YJKLine(hypiping2.StartConnector.Origin, hypiping2.EndConnector.Origin);
			if (this.IsLineOnLine(hyline, hyline2, 0.03))
			{
				result = 10;
			}
			else if (hyline.GetDPLineDistance(otherLine) > diameter * 3.0 || (hyline.IsXYParallel(otherLine) && hyline.GetDistance(hyline2.StartPoint) > diameter * 3.0))
			{
				XYZ origin = hypiping.StartConnector.Origin;
				XYZ origin2 = hypiping.EndConnector.Origin;
				XYZ origin3 = hypiping2.StartConnector.Origin;
				XYZ origin4 = hypiping2.EndConnector.Origin;
				XYZ xyz = new XYZ(origin.X, origin.Y, 0.0);
				XYZ xyz2 = new XYZ(origin2.X, origin2.Y, 0.0);
				XYZ xyz3 = new XYZ(origin3.X, origin3.Y, 0.0);
				XYZ xyz4 = new XYZ(origin4.X, origin4.Y, 0.0);
				if (xyz.DistanceTo(xyz3) < diameter || xyz.DistanceTo(xyz4) < diameter || xyz2.DistanceTo(xyz3) < diameter || xyz2.DistanceTo(xyz4) < diameter)
				{
					result = 22;
				}
				else
				{
					result = 23;
				}
			}
			else if (hyline.IntersectionPoint(otherLine, 0.03) != null)
			{
				if (hypiping.StartConnector.Origin.DistanceTo(hypiping2.StartConnector.Origin) < diameter || hypiping.StartConnector.Origin.DistanceTo(hypiping2.EndConnector.Origin) < diameter || hypiping.EndConnector.Origin.DistanceTo(hypiping2.StartConnector.Origin) < diameter || hypiping.EndConnector.Origin.DistanceTo(hypiping2.EndConnector.Origin) < diameter)
				{
					result = 12;
				}
				else
				{
					result = 13;
				}
			}
			return result;
		}

		public bool IsLineOnLine(YJKLine hyLine1, YJKLine hyLine2, double deviation)
		{
			hyLine1.MakeUnBound();
			return hyLine1.GetDistance(hyLine2.StartPoint) < deviation && hyLine1.GetDistance(hyLine2.EndPoint) < deviation;
		}

		public void SameLineConnPipes(IList<Pipe> pipes, HYPipeConnect myPipeConnect)
		{
			YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(pipes[0]);
			YJKPiping<Pipe> hypiping2 = new YJKPiping<Pipe>(pipes[1]);
			if (hypiping2.Piping.Diameter == hypiping.Piping.Diameter)
			{
				hypiping.Combine(hypiping2.Piping);
				return;
			}
			myPipeConnect.NewTransitionFitting(pipes, 1);
		}

		public void SamePlaneElbowConnPipes(IList<Pipe> pipes)
		{
			this.NewElbowFitting(pipes, true);
		}

		public bool NewElbowFitting(IList<Pipe> pipes, bool beReginerate = true)
		{
			bool flag = false;
			bool result;
			try
			{
				if (pipes.Count < 2)
				{
					throw new System.ArgumentNullException("Pipe", "is null");
				}
				Document document = pipes[0].Document;
				YJKPiping<Pipe> hyPipe = new YJKPiping<Pipe>(pipes[0]);
				YJKPiping<Pipe> hyPipe2 = new YJKPiping<Pipe>(pipes[1]);
				Line line = (pipes[0].Location as LocationCurve).Curve as Line;
				Line line2 = (pipes[1].Location as LocationCurve).Curve as Line;
				YJKLine hyline = new YJKLine(line.GetEndPoint(0), line.GetEndPoint(1));
				new YJKLine(line2.GetEndPoint(0), line2.GetEndPoint(1));
				XYZ xyz = hyline.IntersectionPoint(line2, 0.03);
				if (xyz != null)
				{
					Connector connector = null;
					Connector connector2 = null;
					this.GetOrderPipesConnectors(hyPipe, hyPipe2, xyz, ref connector, ref connector2);
					if (connector != null && connector2 != null && !connector.IsConnected && !connector2.IsConnected)
					{
						document.Create.NewElbowFitting(connector, connector2);
						flag = true;
					}
				}
				if (beReginerate)
				{
					document.Regenerate();
				}
				result = flag;
			}
			catch (Exception)
			{
				throw new Exception("创建管件连接失败，可能由于管道角度过大或者过小！");
			}
			return result;
		}

		public List<Pipe> ExtendPipe(List<Pipe> pipes, XYZ start)
		{
			YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(pipes[0]);
			new YJKPiping<Pipe>(pipes[1]);
			Line line = (pipes[0].Location as LocationCurve).Curve as Line;
			Line line2 = (pipes[1].Location as LocationCurve).Curve as Line;
			YJKLine hyline = new YJKLine(line.GetEndPoint(0), line.GetEndPoint(1));
			new YJKLine(line2.GetEndPoint(0), line2.GetEndPoint(1));
			XYZ xyz = hyline.IntersectionPoint(line2, 0.03);
			if (xyz == null)
			{
				return null;
			}
			XYZ xyz2 = line.GetEndPoint(0);
			XYZ endPoint = line.GetEndPoint(1);
			if (xyz2.DistanceTo(start) < endPoint.DistanceTo(start))
			{
				xyz2 = endPoint;
			}
			Pipe item = hypiping.Extend(xyz2, xyz);
			return new List<Pipe>
			{
				item,
				pipes[1]
			};
		}

		public void GetOrderPipesConnectors(YJKPiping<Pipe> hyPipe1, YJKPiping<Pipe> hyPipe2, XYZ intersectionPoint, ref Connector conn1, ref Connector conn2)
		{
			if (this.JudgeBeMaxPipe(hyPipe1, hyPipe2))
			{
				conn1 = hyPipe1.GetCloseConnector(intersectionPoint, false);
				conn2 = hyPipe2.GetCloseConnector(intersectionPoint, false);
				return;
			}
			conn1 = hyPipe2.GetCloseConnector(intersectionPoint, false);
			conn2 = hyPipe1.GetCloseConnector(intersectionPoint, false);
		}

		public bool JudgeBeMaxPipe(YJKPiping<Pipe> hyPipe1, YJKPiping<Pipe> hyPipe2)
		{
			return hyPipe1.GetDiameter() > hyPipe2.GetDiameter();
		}

		public void SamePlaneTeeConnPipes(IList<Pipe> pipes, HYPipeConnect myPipeConnect)
		{
			pipes.Add(pipes[0]);
			myPipeConnect.NewTeeFitting(ref pipes, true);
		}

		public void AntarafacialElbowConnPipes(IList<Pipe> pipes, HYPipeConnect myPipeConnect, XYZ point)
		{
			YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(pipes[0]);
			YJKPiping<Pipe> hypiping2 = new YJKPiping<Pipe>(pipes[1]);
			Line line = Line.CreateBound(hypiping.StartConnector.Origin, hypiping.EndConnector.Origin);
			Line line2 = Line.CreateBound(hypiping2.StartConnector.Origin, hypiping2.EndConnector.Origin);
			YJKLine xyproject = hypiping.GetXYProject();
			YJKLine xyproject2 = hypiping2.GetXYProject();
			xyproject.MakeUnBound();
			xyproject2.MakeUnBound();
			XYZ xyz = xyproject.IntersectionPoint(xyproject2.Line);
			XYZ xyz2 = new XYZ(0.0, 0.0, 0.0);
			if (xyz != null && !xyz.IsAlmostEqualTo(xyz2, 0.0001))
			{
				XYZ end = new XYZ(xyz.X, xyz.Y, xyz.Z + 10.0);
				YJKLine hyline = new YJKLine(xyz, end);
				hyline.MakeUnBound();
				line.MakeUnbound();
				line2.MakeUnbound();
				XYZ xyz3 = hyline.IntersectionPoint(line);
				XYZ xyz4 = hyline.IntersectionPoint(line2);
				if (xyz3 != null && xyz4 != null && xyz3.DistanceTo(xyz4) > hypiping2.GetDiameter() * 3.0)
				{
					Pipe item = YJKRevitTools.NewPipe(hypiping2.Piping, xyz3, xyz4);
					IList<Pipe> list = new List<Pipe>();
					list.Add(item);
					list.Add(hypiping.Piping);
					myPipeConnect.NewElbowFitting(list, true);
					list.Clear();
					list.Add(item);
					list.Add(hypiping2.Piping);
					myPipeConnect.NewElbowFitting(list, true);
					return;
				}
			}
			else if (xyproject2.GetDistance(xyproject.StartPoint) < 0.016404199475065617)
			{
				Connector closeConnector = hypiping2.GetCloseConnector(point, false);
				XYZ project = hypiping.GetProject(point);
				if (project.DistanceTo(closeConnector.Origin) > hypiping2.GetDiameter() * 3.0)
				{
					Pipe item2 = YJKRevitTools.NewPipe(hypiping2.Piping, closeConnector.Origin, project);
					IList<Pipe> list2 = new List<Pipe>();
					list2.Add(item2);
					list2.Add(hypiping.Piping);
					myPipeConnect.NewElbowFitting(list2, true);
					list2.Clear();
					list2.Add(item2);
					list2.Add(hypiping2.Piping);
					myPipeConnect.NewElbowFitting(list2, true);
				}
			}
		}

		public void AntaraficialTeeConnPipes(IList<Pipe> pipes, HYPipeConnect myPipeConnect, XYZ point)
		{
			YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(pipes[0]);
			YJKPiping<Pipe> hypiping2 = new YJKPiping<Pipe>(pipes[1]);
			Line line = Line.CreateBound(hypiping.StartConnector.Origin, hypiping.EndConnector.Origin);
			Line line2 = Line.CreateBound(hypiping2.StartConnector.Origin, hypiping2.EndConnector.Origin);
			YJKLine xyproject = hypiping.GetXYProject();
			YJKLine xyproject2 = hypiping2.GetXYProject();
			xyproject2.MakeUnBound();
			XYZ xyz = xyproject.IntersectionPoint(xyproject2.Line);
			XYZ xyz2 = new XYZ(0.0, 0.0, 0.0);
			if (xyz != null && !xyz.IsAlmostEqualTo(xyz2, 0.0001))
			{
				XYZ end = new XYZ(xyz.X, xyz.Y, xyz.Z + 10.0);
				YJKLine hyline = new YJKLine(xyz, end);
				hyline.MakeUnBound();
				line.MakeUnbound();
				line2.MakeUnbound();
				XYZ xyz3 = hyline.IntersectionPoint(line);
				XYZ xyz4 = hyline.IntersectionPoint(line2);
				if (xyz3 != null && xyz4 != null && xyz3.DistanceTo(xyz4) > hypiping2.GetDiameter() * 3.0)
				{
					Pipe item = YJKRevitTools.NewPipe(hypiping2.Piping, xyz3, xyz4);
					IList<Pipe> list = new List<Pipe>();
					list.Add(item);
					list.Add(hypiping2.Piping);
					myPipeConnect.NewElbowFitting(list, true);
					list.Clear();
					list.Add(item);
					list.Add(hypiping.Piping);
					list.Add(hypiping.Piping);
					myPipeConnect.NewTeeFitting(ref list, true);
					return;
				}
			}
			else if (xyproject2.GetDistance(xyproject.StartPoint) < 0.016404199475065617)
			{
				Connector closeConnector = hypiping2.GetCloseConnector(point, false);
				XYZ project = hypiping.GetProject(point);
				if (project.DistanceTo(closeConnector.Origin) > hypiping2.GetDiameter() * 3.0)
				{
					Pipe item2 = YJKRevitTools.NewPipe(hypiping2.Piping, closeConnector.Origin, project);
					IList<Pipe> list2 = new List<Pipe>();
					list2.Add(item2);
					list2.Add(hypiping2.Piping);
					myPipeConnect.NewElbowFitting(list2, true);
					list2.Clear();
					list2.Add(item2);
					list2.Add(hypiping.Piping);
					list2.Add(hypiping.Piping);
					myPipeConnect.NewTeeFitting(ref list2, true);
				}
			}
		}

		public bool CrossConnPipes(List<Element> pipes, ref Pipe pipe, XYZ point, HYPipeConnect myPipeConnect)
		{
			try
			{
				SortedDictionary<double, Element> sortedDictionary = new SortedDictionary<double, Element>();
				bool result = false;
				RefrigerantPipeCreate refrigerantPipeCreate = new RefrigerantPipeCreate();
				foreach (Element element in pipes)
				{
					if (refrigerantPipeCreate.FilterPipeType(element as Pipe, pipe))
					{
						Line line = (element.Location as LocationCurve).Curve as Line;
						double distance = new YJKLine(line.GetEndPoint(0), line.GetEndPoint(1)).GetDistance(point);
						sortedDictionary.Add(distance, element);
					}
				}
				foreach (KeyValuePair<double, Element> keyValuePair in sortedDictionary)
				{
					Line line2 = (pipe.Location as LocationCurve).Curve as Line;
					YJKLine hyline = new YJKLine(line2.GetEndPoint(0), line2.GetEndPoint(1));
					Line line3 = (keyValuePair.Value.Location as LocationCurve).Curve as Line;
					if (hyline.IsVertical(line3))
					{
						IList<Pipe> list = new List<Pipe>();
						list.Add(pipe);
						list.Add(pipe);
						list.Add(keyValuePair.Value as Pipe);
						list.Add(keyValuePair.Value as Pipe);
						result = myPipeConnect.NewCrossFitting(ref list, true);
						double num = 0.0;
						foreach (Pipe pipe2 in list)
						{
							XYZ end = new XYZ(point.X, point.Y, point.Z + 10.0);
							YJKLine hyline2 = new YJKLine(point, end);
							Line line4 = (pipe2.Location as LocationCurve).Curve as Line;
							YJKLine hyline3 = new YJKLine(line4.GetEndPoint(0), line4.GetEndPoint(1));
							if (Math.Round(hyline2.GetDPLineDistance(hyline3.Line), 3, MidpointRounding.AwayFromZero) == 0.0)
							{
								double dplineDistance = this.GetDPLineDistance2(hyline3.Line, hyline2);
								if (dplineDistance > num)
								{
									num = dplineDistance;
									pipe = pipe2;
								}
							}
						}
					}
				}
				return result;
			}
			catch (Exception)
			{
			}
			return true;
		}

		public bool CrossElevationConnPipes(List<Element> pipes, Pipe pipe, XYZ point, XYZ vector, HYPipeConnect myPipeConnect)
		{
			try
			{
				SortedDictionary<double, Element> sortedDictionary = new SortedDictionary<double, Element>();
				bool result = false;
				RefrigerantPipeCreate refrigerantPipeCreate = new RefrigerantPipeCreate();
				foreach (Element element in pipes)
				{
					if (refrigerantPipeCreate.FilterPipeType(element as Pipe, pipe))
					{
						Line line = (element.Location as LocationCurve).Curve as Line;
						double distance = new YJKLine(line.GetEndPoint(0), line.GetEndPoint(1)).GetDistance(point);
						sortedDictionary.Add(distance, element);
					}
				}
				foreach (KeyValuePair<double, Element> keyValuePair in sortedDictionary)
				{
					Line line2 = (pipe.Location as LocationCurve).Curve as Line;
					YJKLine hyline = new YJKLine(line2.GetEndPoint(0), line2.GetEndPoint(1));
					Line line3 = (keyValuePair.Value.Location as LocationCurve).Curve as Line;
					if (hyline.IsVertical(line3))
					{
						IList<Pipe> list = new List<Pipe>();
						list.Add(pipe);
						list.Add(pipe);
						list.Add(keyValuePair.Value as Pipe);
						list.Add(keyValuePair.Value as Pipe);
						result = myPipeConnect.NewCrossFitting(ref list, true);
						double num = 0.0;
						foreach (Pipe pipe2 in list)
						{
							XYZ end = point.Add(vector);
							YJKLine hyline2 = new YJKLine(point, end);
							Line line4 = (pipe2.Location as LocationCurve).Curve as Line;
							YJKLine hyline3 = new YJKLine(line4.GetEndPoint(0), line4.GetEndPoint(1));
							if (Math.Round(hyline2.GetDPLineDistance(hyline3.Line), 3, MidpointRounding.AwayFromZero) == 0.0)
							{
								double dplineDistance = this.GetDPLineDistance2(hyline3.Line, hyline2);
								if (dplineDistance > num)
								{
									num = dplineDistance;
									pipe = pipe2;
								}
							}
						}
					}
				}
				return result;
			}
			catch (Exception)
			{
			}
			return true;
		}

		public static YJKWindowHandle hWndRevit;
	}
}
